﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <customqstandarditemmodel.h>

void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
    event->acceptProposedAction();
}
void MainWindow::dropEvent(QDropEvent *event)
{
    QString name = event->mimeData()->urls().first().toLocalFile();

    ui->LineEditDriverPath->setText(name);

    qDebug()<<"name:"<<name;
}

MainWindow::~MainWindow()
{
    delete ui;
}


ULONG_PTR SystemService::LoadLibraryA32 =(ULONG_PTR)0;
ULONG_PTR SystemService::LoadLibraryA64 =(ULONG_PTR)0;
LdrLoadDllDef SystemService::LdrLoadDll64 =(LdrLoadDllDef)0;
ULONG SystemService::ShellCodeLength = 0;
NtTerminateThreadDef SystemService::NtTerminateThread = (NtTerminateThreadDef)0;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setWindowIcon(QIcon(":/new/prefix1/AquaOS.ico"));
    this->setAcceptDrops(true);

    //初始化系统服务
    systemService.InitializationEnvironment();
    // 设置tableview隐藏序号列
    ui->TableViewProcessList->verticalHeader()->hide();
    this->SetTableViewHeader();
    qTimeId = this->startTimer(PROCESS_FLUSH_TIME);
    //初始化状态栏QLabel
    qLableStatus = new QLabel(this);
    ui->statusBar->addWidget(qLableStatus);
    //获取操作系统内核信息
    OSVersionBean osVersionBean;
    bool IsOk =  systemService.GetSystemAndNtVersion(&osVersionBean);
    if (IsOk) {
        QLabel* qLableOsVersionName = new QLabel(this);
        qLableOsVersionName->setText(osVersionBean.OSVersionName);
        ui->statusBar->addWidget(qLableOsVersionName);

        QLabel* qLableOsSPName = new QLabel(this);
        qLableOsSPName->setText(osVersionBean.SPVersionName);
        ui->statusBar->addWidget(qLableOsSPName);


        QLabel* qLableNTName = new QLabel(this);
        QString NTLable;
        NTLable.append("NT:").append(osVersionBean.NTVersionName).append(" Build:").append(osVersionBean.KernelBuildName);
        qLableNTName->setText(NTLable);
        ui->statusBar->addWidget(qLableNTName);
    }





    //this->installEventFilter(this);
    //为输入框注册事件过滤处理
    ui->lineEditInputPid0->installEventFilter(this);
    ui->lineEditInputPid1->installEventFilter(this);
    //模块操作按钮
    ui->ButtonModuleRefrensh->installEventFilter(this);
    ui->ButtonModuleToThread->installEventFilter(this);
    ui->ButtonPositioningModuleFile->installEventFilter(this);
    ui->ButtonUnloadModule->installEventFilter(this);
    ui->ButtonEnumHideModule->installEventFilter(this);
    //线程操作按钮
    ui->ButtonThreadResume->installEventFilter(this);
    ui->ButtonThreadSuppend->installEventFilter(this);
    ui->ButtonThreadToModule->installEventFilter(this);
    ui->ButtonThreadRefrensh->installEventFilter(this);
    ui->ButtonThreadTerminate->installEventFilter(this);
    //进程操作按钮
    ui->ButtonTerminateProcess->installEventFilter(this);
    ui->ButtonResumeProcess->installEventFilter(this);
    ui->ButtonSuppendProcess->installEventFilter(this);
    ui->ButtonExtractIcon->installEventFilter(this);
    ui->ButtonInjectDll->installEventFilter(this);
    ui->ButtonMemoryRange->installEventFilter(this);
    ui->ButtonCreateThread->installEventFilter(this);
    ui->ButtonConvertToMachineCode->installEventFilter(this);

    processService.EnableDebugPrivilege();

    //设置输入框只接受数字,范围为0~ 1000000
    ui->lineEditInputPid0->setValidator(new QIntValidator(0, 1000000, this)); //设置范围为0~ 1000000
    ui->lineEditInputPid1->setValidator(new QIntValidator(0, 1000000, this)); //设置范围为0~ 1000000
    //初始化反汇编窗口
    this->InitializationAssemblyTable();
    ui->TableViewAssembly->verticalHeader()->hide();

}


//设置进制列表的头部数据
VOID MainWindow::SetTableViewHeader()
{
    QString processListHead[]={"进程名","进程ID","父进程ID","路径","Eprocess","属性","文件厂商"};
    QString processThreadListHead[]={"线程ID","ETHREAD","Teb","优先级","线程入口","模块","引用计数","线程状态"};
    QString processModuleListHead[]={"模块路径","加载基址","模块大小","入口地址","文件厂商"};
    QString AssemblyListHead[]={"Address","Bytes","Opcode","Comment"};
    QString DriverListHead[]={"DriverName","Operation","Result","LastError"};

    ProcessColumnCount = sizeof(processListHead)/sizeof(PVOID);
    ProcessModuleColumnCount = sizeof(processModuleListHead)/sizeof(PVOID);
    ProcessThreadColumnCount = sizeof(processThreadListHead)/sizeof(PVOID);
    AssemblyColumnCount = sizeof(AssemblyListHead)/sizeof(PVOID);
    DriverColumnCount = sizeof(DriverListHead)/sizeof(PVOID);

    processTableViewDataModule = new CustomQStandardItemModel();
    processModuleTableViewDataModule = new CustomQStandardItemModel();
    processThreadTableViewDataModule = new CustomQStandardItemModel();
    AssemblyTableViewDataModule = new CustomQStandardItemModel();
    DriverTableViewDataModule = new CustomQStandardItemModel();


    ui->TableViewProcessList->setModel(processTableViewDataModule);
    ui->TableViewAssembly->setModel(AssemblyTableViewDataModule);
    ui->TableViewProcessModuleList->setModel(processModuleTableViewDataModule);
    ui->TableViewProcessThreadList->setModel(processThreadTableViewDataModule);
    ui->TableViewShowDriverLogger->setModel(DriverTableViewDataModule);

    //设置表格为选中单行数据
    ui->TableViewProcessList->setSelectionMode(QAbstractItemView::SingleSelection);
    ui->TableViewProcessModuleList->setSelectionMode(QAbstractItemView::SingleSelection);
    ui->TableViewProcessThreadList->setSelectionMode(QAbstractItemView::SingleSelection);
    ui->TableViewAssembly->setSelectionMode(QAbstractItemView::SingleSelection);
    ui->TableViewShowDriverLogger->setSelectionMode(QAbstractItemView::SingleSelection);

    //设置整行选中
    ui->TableViewProcessList->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->TableViewProcessModuleList->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->TableViewProcessThreadList->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->TableViewAssembly->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->TableViewShowDriverLogger->setSelectionBehavior(QAbstractItemView::SelectRows);




    //表格只读
    ui->TableViewShowDriverLogger->setEditTriggers(QAbstractItemView::NoEditTriggers);
    //均分列
    ui->TableViewShowDriverLogger->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    // 设置tableview隐藏序号列
    ui->TableViewShowDriverLogger->verticalHeader()->hide();

    for (ULONG index = 0; index < DriverColumnCount; ++index)
    {
        //设置表格标题
        DriverTableViewDataModule->setHorizontalHeaderItem(index, new QStandardItem(DriverListHead[index]));
    }

    //表格只读
    ui->TableViewProcessList->setEditTriggers(QAbstractItemView::NoEditTriggers);
    //启用右键菜单
    ui->TableViewProcessList->setContextMenuPolicy(Qt::CustomContextMenu);
    for (ULONG index = 0; index < ProcessColumnCount; ++index)
    {
        //设置表格标题
        processTableViewDataModule->setHorizontalHeaderItem(index, new QStandardItem(processListHead[index]));
        if (index==3) {
            //设置固定的宽度
            ui->TableViewProcessList->setColumnWidth(index,380);
        }else {
            //设置表格的列的宽度值
            // ui->TableViewProcessList->setColumnWidth(index,80);
            //根据列内容来定列宽
            ui->TableViewProcessList->horizontalHeader()->setSectionResizeMode(index,QHeaderView::ResizeToContents );
        }

    }


    for (ULONG index = 0; index < ProcessModuleColumnCount; ++index)
    {
        //设置表格标题
        processModuleTableViewDataModule->setHorizontalHeaderItem(index, new QStandardItem(processModuleListHead[index]));
        if (index==0) {
            //设置固定的宽度
            ui->TableViewProcessModuleList->setColumnWidth(index,400);
        }else {
            //设置表格的列的宽度值
            // ui->TableViewProcessList->setColumnWidth(index,80);
            //根据列内容来定列宽
            ui->TableViewProcessModuleList->horizontalHeader()->setSectionResizeMode(index,QHeaderView::ResizeToContents );
        }
    }



    //设置列只读(第0列只读)
    ui->TableViewProcessThreadList->setItemDelegateForColumn(0,new ReadOnlyDelegate());
    for (ULONG index = 0; index < ProcessThreadColumnCount; ++index)
    {
        //设置表格标题
        processThreadTableViewDataModule->setHorizontalHeaderItem(index, new QStandardItem(processThreadListHead[index]));
        //根据列内容来定列宽
        ui->TableViewProcessThreadList->horizontalHeader()->setSectionResizeMode(index,QHeaderView::ResizeToContents );
    }
    //禁止拖拽列的宽度
    //ui->TableViewProcessList->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);//对第0列单独设置固定宽度
    //ui->TableViewAssembly->setFocusPolicy(Qt::NoFocus);
    //隐藏表格聚焦虚线
    ui->TableViewAssembly->setItemDelegate(new CommonDelegate());
    //隐藏水平滚动条
    ui->TableViewAssembly->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    //可弹出右键菜单
    ui->TableViewAssembly->setContextMenuPolicy(Qt::CustomContextMenu);
    //均分列
    ui->TableViewAssembly->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    //表格只读
    ui->TableViewAssembly->setEditTriggers(QAbstractItemView::NoEditTriggers);
    for (ULONG index = 0; index < AssemblyColumnCount; ++index)
    {
        //设置表格标题
        AssemblyTableViewDataModule->setHorizontalHeaderItem(index, new QStandardItem(AssemblyListHead[index]));
    }

    assemblyQmenu = new QMenu(ui->TableViewAssembly);
    QAction *qActionGotoAddress = new QAction("跳转到->");
    QAction *retnInjectWindow = new QAction("返回注入窗口");
    assemblyQmenu->addAction(qActionGotoAddress);
    assemblyQmenu->addAction(retnInjectWindow);
    //设置槽函数
    connect(ui->TableViewAssembly, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(DisplayAssemblyMenu(QPoint)));
    connect(retnInjectWindow,&QAction::triggered,
            [=](){
        //返回到注入窗口
        ui->StackedWidgetInject->setCurrentWidget(ui->PageInject);
    });
    //给跳转菜单绑定事件
    connect(qActionGotoAddress,&QAction::triggered,
            [=](){



        bool isOK;
        QString text = QInputDialog::getText(this, tr("跳转"),
                                             tr("请输入要跳转到的地址"),
                                             QLineEdit::Normal,
                                             tr("0x400000"),
                                             &isOK);
        if (isOK && !text.isEmpty()) {

            if (text.startsWith("0X",Qt::CaseInsensitive))
            {
                text.remove(0,2);
            }
            ULONG_PTR inputDisassemble = (ULONG_PTR)text.toULongLong(NULL,16);
            ProcessBean processBean;
            if (GetSelectProcessInfo(&processBean))
            {

                HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,false,processBean.pId);
                PUCHAR buffer = new UCHAR[PAGE_SIZE];
                RtlZeroMemory(buffer,PAGE_SIZE);
                SIZE_T lpNumberOfReads=0;
                WINBOOL isReadSuccess= ReadProcessMemory(hProcess,(LPCVOID)inputDisassemble,buffer,PAGE_SIZE,&lpNumberOfReads);
                ULONG_PTR startDisassemble =(ULONG_PTR) buffer;
                if (isReadSuccess && lpNumberOfReads)
                {
                    AssemblyTableViewDataModule->removeRows(0,AssemblyTableViewDataModule->rowCount());

                    //                    ui->TableViewAssembly->setUpdatesEnabled(false);  //暂停界面刷新

                    ud_t udObject;
                    char assembly[AssemblyStringBufferLength];
                    for (int rowIndex = 0; rowIndex < 1000; ++rowIndex)
                    {
                        RtlZeroMemory(assembly,AssemblyStringBufferLength);
                        ULONG length = disassembleService.disassemble(
                                    &udObject
                                    ,assembly
                                    ,inputDisassemble
                                    ,startDisassemble
                                    ,(DisassembleMode)processBean.bit);
                        //地址
                        QStandardItem* item0 = new QStandardItem(QString("0x").append("%1").arg(inputDisassemble,16,16,QChar('0')).toUpper());
                        QString code;
                        for (ULONG var = 0; var < length; ++var) {
                            code.append(QString("%1 ").arg(*(PUCHAR)(startDisassemble+var),2,16,QChar('0')).toUpper());
                        }
                        QStandardItem* item1 = new QStandardItem(code);
                        //十六进制硬编码
                        //汇编指令
                        QStandardItem* item2 = new QStandardItem(QString::fromLocal8Bit(assembly));
                        //Comments
                        QStandardItem* item3 = new QStandardItem(QString());

                        QList<QStandardItem*> item;
                        item<<item0 << item1 << item2 << item3;
                        AssemblyTableViewDataModule->appendRow(item);
                        startDisassemble+=length;
                        inputDisassemble+=length;
                    }
                    //                    ui->TableViewAssembly->setUpdatesEnabled(true);  //恢复界面刷新

                }
                SafeDelete(buffer);
            }
        }

    });
}




void MainWindow::DisplayAssemblyMenu(QPoint pos)
{
    QModelIndex index = ui->TableViewAssembly->indexAt(pos);
    if (index.isValid())
    {
        assemblyQmenu->exec(QCursor::pos()); // 菜单出现的位置为当前鼠标的位置
    }
}




//初始化汇编表格
VOID MainWindow::InitializationAssemblyTable()
{
    for (int rowIndex = 0; rowIndex < 0x1000; ++rowIndex) {
        //地址
        QStandardItem* item0 = new QStandardItem(QString("0x").append("%1").arg(rowIndex,16,16,QChar('0')).toUpper());
        //十六进制硬编码
        QStandardItem* item1 = new QStandardItem(QString());
        //汇编指令
        QStandardItem* item2 = new QStandardItem(QString("??"));
        //Comments
        QStandardItem* item3 = new QStandardItem(QString());

        QList<QStandardItem*> item;
        item<<item0 << item1 << item2 << item3 ;
        AssemblyTableViewDataModule->appendRow(item);
    }
    ui->TableViewAssembly->setShowGrid(false);
}

VOID  MainWindow::timerEvent(QTimerEvent *event)
{
    if (qTimeId==event->timerId()) {
        //定时器定时刷新进程列表
        this->RefreshProcessListTableView();
    }
}
//刷新进程列表
VOID MainWindow::RefreshProcessListTableView()
{
    //重新获取进程列表数据
    QList<ProcessBean> processBeanList;
    processService.CreateProcessListSnapshot(&processBeanList);
    //比对表格中的进程列表数据是否存在于最新的进程列表快照中
    for (int rowIndex = 0; rowIndex < processTableViewDataModule->rowCount(); ++rowIndex)
    {
        //获取行的第一列数据
        QStandardItem* qStandardItem = processTableViewDataModule->item(rowIndex,1);
        //获取进程id
        ULONG dwPId = qStandardItem->text().toInt();
        ProcessBean processBean;
        processBean.pId=dwPId;
        //判断最新快照是否存在表格当中的数据,不存在则说明进程已经退出,删除当前行数据
        if (!processBeanList.contains(processBean)) {
            QString szExeName = processTableViewDataModule->index(rowIndex,0).data().toString();
            //选中的进程,已经退出,从数据模型中删除当前行数据
            processTableViewDataModule->removeRow(rowIndex);
            ULONG selectPId;
            if (GetSelectPId(&selectPId))
            {
                //qDebug()<<"删除进程id："<<dwPId;
                if (selectPId==dwPId)
                {
                    ProcessBean psb;
                    psb.pName = szExeName;
                    //重新校准选中的id
                    this->SetSelectProcessIconAndInput(dwPId,&psb,RemoveProcess);
                    //当进程列表刷新时,被选中的进程退出,此时刷新线程列表和模块列表
                    this->RefreshProcessModuleListTable(NOT_EXIST_PROCESS_ID);
                    this->RefreshProcessThreadListTable(NOT_EXIST_PROCESS_ID);
                }
            }
        }
    }
    //遍历进程列表
    for (int rowIndex = 0; rowIndex < processBeanList.size(); ++rowIndex)
    {
        ProcessBean processBean =  processBeanList.at(rowIndex);
        QList<QStandardItem*> isTableViewContains
                =   processTableViewDataModule->findItems(QString("%1").arg(processBean.pId), Qt::MatchExactly, 1);
        if (!isTableViewContains.size())
        {
            //说明上一轮的进程列表快照中不存在当前进程id,添加行数据显示进程id
            //            qDebug()<<"新增进程id："<<processBean.pId;

            QPixmap qPixmap = processService.GetFileIcon(processBean.pPath);
            //设置进程名和图标
            QStandardItem* item0 = new QStandardItem(QIcon(qPixmap),processBean.pName);
            //设置进程id
            QStandardItem* item1 = new QStandardItem(QString::number(processBean.pId, 10));
            //设置进程父id
            QStandardItem* item2 = new QStandardItem(QString::number(processBean.parentPId, 10));
            //设置进程路径
            QStandardItem* item3 = new QStandardItem(processBean.pPath);
            //设置进程EProcess
            QStandardItem* item4 = new QStandardItem("");
            //进程属性(位数)
            QString bit;
            if (processBean.bit) {
                bit = QString("%1").arg(processBean.bit);
            }
            QStandardItem* item5 = new QStandardItem(bit);

            //公司名称
            QStandardItem* item6 = new QStandardItem(processBean.companyName);
            QList<QStandardItem*> item;
            item<<item0 << item1 << item2 << item3 << item4<< item5 <<item6;
            processTableViewDataModule->insertRow(rowIndex,item);

        }

    }

    qLableStatus->setText(QString("进程数量:%1").arg(processBeanList.size()));
    //设置单元格文本颜色，张三的数据设置为红色
    //processTableViewDataModule->item(index, index)->setForeground(QBrush(QColor(255, 0, 0)));

    //设置单元格文本居中，数据设置为居中显示
    //processTableViewDataModule->item(index, index)->setTextAlignment(Qt::AlignCenter);
    //设置排序方式
    //processTableViewDataModule->sort(1, Qt::AscendingOrder);

    return ;
}
//点击进程事件,查询进程模块和线程列表
void MainWindow::on_TableViewProcessList_clicked(const QModelIndex &index)
{
    if (index.isValid())
    {
        //选中行的下标
        int selectRow = index.row();
        //获取选中行的第一列的值：进程id
        ULONG dwPId = processTableViewDataModule->index(selectRow,1).data().toInt();
        ULONG selectedPId;
        if (GetSelectPId(&selectedPId))
        {
            if (selectedPId==dwPId)
            {
                //如果重复点击选中的进程ID,则不进行再次处理
                return;
            }
        }
        ProcessBean processBean;
        processBean.pId=dwPId;
        processBean.pName = processTableViewDataModule->index(selectRow,0).data().toString();
        processBean.pPath = processTableViewDataModule->index(selectRow,3).data().toString();
        this->SetSelectProcessIconAndInput(dwPId,&processBean,ClickProcessTableView);
        this->RefreshProcessModuleListTable(dwPId);
        this->RefreshProcessThreadListTable(dwPId);
    }
}



//填充模块表格数据
void MainWindow::FillProcessModuleListTable(QList<ProcessModuleBean>qProcessModuleList)
{
    for (int rowIndex = 0; rowIndex < qProcessModuleList.size(); ++rowIndex)
    {
        //按下标获取模块信息
        ProcessModuleBean processModuleBean =  qProcessModuleList.at(rowIndex);
        //填充模块TableView的数据
        //模块路径
        processModuleTableViewDataModule->setItem(rowIndex,0,new QStandardItem(processModuleBean.modulePath));
        //模块基址
        processModuleTableViewDataModule->setItem(rowIndex, 1, new QStandardItem(QString("0x%1").arg(processModuleBean.moduleAddress,16,16, QChar('0'))));
        //模块大小
        processModuleTableViewDataModule->setItem(rowIndex, 2, new QStandardItem(QString("0x%1").arg(processModuleBean.moduleSize,16,16, QChar('0')) ));
        //入口地址
        processModuleTableViewDataModule->setItem(rowIndex, 3, new QStandardItem(QString("0x%1").arg(processModuleBean.moduleEntryPoint,16,16, QChar('0'))));
        //公司名称
        processModuleTableViewDataModule->setItem(rowIndex, 4, new QStandardItem(processModuleBean.companyName));
    }
}


//刷新模块列表
void MainWindow::RefreshProcessModuleListTable(ULONG dwPId)
{
    //清空模块列表信息,重新装载数据
    processModuleTableViewDataModule->removeRows(0,processModuleTableViewDataModule->rowCount());
    if (dwPId!=NOT_EXIST_PROCESS_ID)
    {
        //返回进程模块列表
        QList<ProcessModuleBean>qProcessModuleList;
        //获取选中进程的模块列表
        bool isOk = processService.CreateProcessModuleListSnapshot(dwPId,&qProcessModuleList);
        if (isOk)
        {
            ui->LabelModuleCount->setText(QString("<h4 style='color:black'>模块总数:%1</h4>").arg(qProcessModuleList.size()));
            //填充表格数据
            this->FillProcessModuleListTable(qProcessModuleList);
        }else {
            qDebug()<<"无法枚举当前进程模块";
            ui->LabelModuleCount->setText(QString("<h4 style='color:red'>无法枚举当前进程模块</h4>"));
        }
        //清空LIST便于内存回收
        qProcessModuleList.clear();
    }
}

void MainWindow::RefreshProcessThreadListTable(ULONG dwPId)
{
    //清空模块列表信息,重新装载数据
    processThreadTableViewDataModule->removeRows(0,processThreadTableViewDataModule->rowCount());
    if (dwPId!=NOT_EXIST_PROCESS_ID)
    {
        //返回进程模块列表
        QList<ProcessThreadBean>qProcessThreadList;
        //获取选中进程的模块列表
        bool isOk = processService.GetProcessThreadList(dwPId,&qProcessThreadList);
        if (isOk) {
            ui->LabelThreadCount->setText(QString("<h4 style='color:black'>线程总数:%1</h4>").arg(qProcessThreadList.size()));
            for (int rowIndex = 0; rowIndex < qProcessThreadList.size(); ++rowIndex) {
                //按下标获取模块信息
                ProcessThreadBean processThreadBean =  qProcessThreadList.at(rowIndex);
                //填充模块TableView的数据
                //线程id
                processThreadTableViewDataModule->setItem(rowIndex,0,new QStandardItem(QString::number(processThreadBean.threadId,10)));
                //Ethread
                processThreadTableViewDataModule->setItem(rowIndex,1,new QStandardItem(QString()));
                //teb
                processThreadTableViewDataModule->setItem(rowIndex,2, new QStandardItem(QString("0x%1").arg(processThreadBean.teb,16,16, QChar('0'))));
                //优先级
                processThreadTableViewDataModule->setItem(rowIndex,3, new QStandardItem(QString::number(processThreadBean.Priority,10)));
                //线程入口点
                processThreadTableViewDataModule->setItem(rowIndex,4, new QStandardItem(QString("0x%1").arg(processThreadBean.threadEntryPoint,16,16, QChar('0'))));
                //模块名称
                processThreadTableViewDataModule->setItem(rowIndex,5, new QStandardItem(QFileInfo(QString::fromWCharArray(processThreadBean.moudleName)).fileName()));
                //引用计数
                processThreadTableViewDataModule->setItem(rowIndex,6, new QStandardItem(QString::number(processThreadBean.cntUsage,10)));
                //状态
                processThreadTableViewDataModule->setItem(rowIndex,7, new QStandardItem(
                                                              processService.GetThreadStateString((THREAD_STATE)processThreadBean.status,(KWAIT_REASON)processThreadBean.waitReason)));
            }
        }else {
            qDebug()<<"无法枚举当前进程线程列表";
            ui->LabelThreadCount->setText(QString("<h4 style='color:red'>无法枚举当前进程线程</h4>"));
        }
        //清空LIST便于内存回收
        qProcessThreadList.clear();
    }
}

//清空选中进程区域
VOID MainWindow::ClearSelectPIdArea()
{
    ui->LineEditSelectPid0->clear();
    ui->LineEditSelectPName0->clear();
    ui->LabelSelectProcessIcon0->clear();
    ui->LineEditSelectPid1->clear();
    ui->LineEditSelectPName1->clear();
    ui->LabelSelectProcessIcon1->clear();
}
//设置选中进程区域字段
VOID MainWindow::SetSelectPIdArea(ULONG dwPId,QString dwPName,QString dwPPath)
{
    //设置选中的进程id
    ui->LineEditSelectPid0->setText(QString("%1").arg(dwPId));
    ui->LineEditSelectPName0->setText(dwPName);
    ui->LabelSelectProcessIcon0->setPixmap(processService.GetFileIcon(dwPPath));
    ui->LineEditSelectPid1->setText(QString("%1").arg(dwPId));
    ui->LineEditSelectPName1->setText(dwPName);
    ui->LabelSelectProcessIcon1->setPixmap(processService.GetFileIcon(dwPPath));
}
//显示选中进程标签的提示标语
VOID MainWindow::SetAllPIdTip(QString selectPIdTip)
{
    ui->LabelFindPidTip0->setText(selectPIdTip);
    ui->LabelFindPidTip1->setText(selectPIdTip);
}
//清除选中进程标签的提示标语
VOID MainWindow::ClearAllPIdTip()
{
    ui->LabelFindPidTip0->clear();
    ui->LabelFindPidTip1->clear();
}


//设置选中进程的图标并填充选中进程id名称等信息
bool MainWindow::SetSelectProcessIconAndInput(const int dwParamPId,PProcessBean pProcessBean,FillSelectPId type)
{
    QString dwPName;
    QString dwPPath;
    QString selectPIdTip;
    switch (type)
    {
    case FillSelectPId::RemoveProcess:
    {
        this->ClearSelectPIdArea();
        selectPIdTip = QString("<h4 style='color:red'>已终止的进程id:%1 szExeName:%2</h4>")
                .arg(dwParamPId)
                .arg(pProcessBean->pName);
        this->SetAllPIdTip(selectPIdTip);
        break;
    }
    case FillSelectPId::InputProcessId:
    {
        //遍历TableView,获取选中进程id
        for (int rowIndex = 0; rowIndex < processTableViewDataModule->rowCount(); ++rowIndex)
        {
            //获取行的第一列数据
            QStandardItem* qStandardItem = processTableViewDataModule->item(rowIndex,1);
            //获取进程id
            int dwPId = qStandardItem->text().toInt();
            //如果在表格中搜索到输入的进程id,则设置选中框
            if (dwParamPId==dwPId)
            {
                dwPName = processTableViewDataModule->index(rowIndex,0).data().toString();
                dwPPath = processTableViewDataModule->index(rowIndex,3).data().toString();
                this->ClearAllPIdTip();
                this->SetSelectPIdArea(dwParamPId,dwPName,dwPPath);
                return true;
            }
        }
        selectPIdTip = QString("<h4 style='color:red'>不存在的进程id:%1</h4>").arg(dwParamPId);
        this->SetAllPIdTip(selectPIdTip);
        break;
    }
    case FillSelectPId::ClickProcessTableView:
        dwPName =   pProcessBean->pName;
        dwPPath =   pProcessBean->pPath;
        this->ClearAllPIdTip();
        this->SetSelectPIdArea(dwParamPId,dwPName,dwPPath);
        break;
    default:
        break;
    }
    return false;
}
//获取选中的进程id
bool  MainWindow::GetSelectPId(PULONG dwPId)
{
    QString pIdText = ui->LineEditSelectPid0->text();
    if (!pIdText.isEmpty())
    {
        //返回选中进程id
        *dwPId = pIdText.toInt();
        return true;
    }
    return false;
}

//获取选中的进程详细信息
bool  MainWindow::GetSelectProcessInfo(PProcessBean pProcessBean)
{
    QString pIdText = ui->LineEditSelectPid0->text();
    if (!pIdText.isEmpty()) {
        //恢复线程后刷新线程列表,方便查看线程状态
        int dwPId = pIdText.toInt();

        //比对表格中的进程列表数据是否存在于最新的进程列表快照中
        for (int rowIndex = 0; rowIndex < processTableViewDataModule->rowCount(); ++rowIndex)
        {
            //获取行的第一列数据
            QStandardItem* qStandardItem = processTableViewDataModule->item(rowIndex,1);
            //获取表格数据中的进程id匹配项
            int tViewDwPId = qStandardItem->text().toInt();
            if (dwPId == tViewDwPId)
            {
                //封装选中进程的所有信息
                pProcessBean->pName=        processTableViewDataModule->item(rowIndex, 0)->text();
                pProcessBean->pId=          processTableViewDataModule->item(rowIndex, 1)->text().toInt();
                pProcessBean->parentPId=    processTableViewDataModule->item(rowIndex, 2)->text().toInt();
                pProcessBean->pPath=        processTableViewDataModule->item(rowIndex, 3)->text();
                pProcessBean->eprocess=     processTableViewDataModule->item(rowIndex, 4)->text().toULongLong();
                pProcessBean->bit=          processTableViewDataModule->item(rowIndex, 5)->text().toInt();
                pProcessBean->companyName=  processTableViewDataModule->item(rowIndex, 6)->text();
                return true;
            }
        }
    }
    return false;
}



bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
    if (watched==ui->lineEditInputPid0)
    {
        if (event->type()==QEvent::FocusIn)
        {
            qDebug()<<"lineEditInputPid0 FocusIn";
        }
        else if (event->type()==QEvent::FocusOut)
        {
            QString inputdwPIdText = ui->lineEditInputPid0->text();
            if (!inputdwPIdText.isEmpty())
            {
                int dwPId = inputdwPIdText.toInt();
                bool isSelect = this->SetSelectProcessIconAndInput(dwPId,NULL,InputProcessId);
                if (isSelect)
                {
                    //如果输入框中输入的进程id,选中了进程,则刷新列表
                    this->RefreshProcessThreadListTable(dwPId);
                    this->RefreshProcessModuleListTable(dwPId);
                }
                qDebug()<<"lineEditInputPid0 FocusOut"<<dwPId;
            }
        }
    }
    if (watched==ui->lineEditInputPid1)
    {
        if (event->type()==QEvent::FocusIn)
        {
            qDebug()<<"lineEditInputPid1 FocusIn";
        }
        else if (event->type()==QEvent::FocusOut)
        {
            QString inputdwPIdText = ui->lineEditInputPid1->text();
            if (!inputdwPIdText.isEmpty())
            {
                int dwPId = inputdwPIdText.toInt();
                bool isSelect = this->SetSelectProcessIconAndInput(dwPId,NULL,InputProcessId);
                if (isSelect)
                {
                    //如果输入框中输入的进程id,选中了进程,则刷新列表
                    this->RefreshProcessThreadListTable(dwPId);
                    this->RefreshProcessModuleListTable(dwPId);
                }
                qDebug()<<"lineEditInputPid0 FocusOut"<<dwPId;
            }
        }
    }

    //统一处理按钮点击事件
    if (event->type() == QEvent::MouseButtonPress)
    {
        QMouseEvent* qme =(QMouseEvent*) event;
        if (qme->button()==Qt::LeftButton)
        {
            //枚举隐藏模块
            if (watched==ui->ButtonEnumHideModule)
            {
                ProcessBean processBean;
                if (GetSelectProcessInfo(&processBean))
                {
                    int ret = QMessageBox::warning(
                                this, tr("枚举隐藏模块"),
                                tr("当前操作将要扫描用户态所有内存区域,可能等待时间较长！并失去响应!\n"
                                   "确认要继续吗？"),
                                QMessageBox::Ok |  QMessageBox::Cancel,//显示哪些按钮
                                QMessageBox::Ok);//默认选中哪个按钮
                    switch (ret) {
                    case QMessageBox::Ok:
                    {
                        //返回进程模块列表
                        QList<ProcessModuleBean>qProcessModuleList;
                        if ( processService.EnumProcessModules(processBean.pId,&qProcessModuleList))
                        {
                            processModuleTableViewDataModule->removeRows(0,processModuleTableViewDataModule->rowCount());
                            ui->LabelModuleCount->setText(QString("<h4 style='color:black'>扫描已完成！模块总数:%1</h4>").arg(qProcessModuleList.size()));
                            //重新填充模块数据
                            this->FillProcessModuleListTable(qProcessModuleList);
                            qProcessModuleList.clear();
                            processService.CreateProcessModuleListSnapshot(processBean.pId,&qProcessModuleList);
                            for (int rowIndex = 0; rowIndex < processModuleTableViewDataModule->rowCount(); ++rowIndex)
                            {
                                //获取行的第一列数据
                                QStandardItem* qStandardItem = processModuleTableViewDataModule->item(rowIndex,1);
                                //获取进程id
                                ULONG_PTR moduleAddress = qStandardItem->text().replace(0,2,"").toULongLong(NULL,16);
                                ProcessModuleBean processModuleListBean;
                                processModuleListBean.moduleAddress = moduleAddress;
                                //判断最新快照是否存在表格当中的数据,不存在则说明进程已经退出,删除当前行数据
                                if (!qProcessModuleList.contains(processModuleListBean)) {
                                    //说明是隐藏的模块,使用模块快照API未获取到的模块,红色显示
                                    for (ULONG columnIndex = 0; columnIndex < ProcessModuleColumnCount; ++columnIndex)
                                    {
                                        //设置单元格文本颜色为红色
                                        processModuleTableViewDataModule->item(rowIndex, columnIndex)->setForeground(QBrush(QColor(255, 0, 0)));
                                    }
                                    //设置排序方式
                                    processModuleTableViewDataModule->sort(1, Qt::AscendingOrder);

                                }
                            }
                        }
                        break;
                    }
                    case QMessageBox::Cancel:
                        // Cancel was clicked
                        break;
                    default:
                        // should never be reached
                        break;
                    }
                }
            }
            //切换至线程列表
            if (watched==ui->ButtonModuleToThread)
            {
                ui->stackedWidget->setCurrentWidget(ui->PageThread);
            }


            //切换至反汇编视图
            if (watched==ui->ButtonMemoryRange)
            {
                ui->StackedWidgetInject->setCurrentWidget(ui->PageMemoryRange);
            }

            //注入DLL
            if (watched==ui->ButtonInjectDll)
            {
                QStringList files = QFileDialog::getOpenFileNames(
                            this,
                            "Select one or more files to open",
                            "C:\\Users\\Administrator\\Desktop\\",
                            "DLL(*.dll);;all(*.*)");
                ProcessBean processBean;
                if (GetSelectProcessInfo(&processBean))
                {
                    foreach (QString selectSzExePath, files)
                    {
                        qDebug()<<"filesize:"<<files.size()<<"var:"<<selectSzExePath;
                        processService.InjectDllToProcess(processBean.pId,selectSzExePath);
                    }
                }
            }
            //提取进程图标
            if (watched==ui->ButtonExtractIcon)
            {
                ProcessBean processBean;
                if (GetSelectProcessInfo(&processBean))
                {
                    QString processPath =    processTableViewDataModule->index(ui->TableViewProcessList->currentIndex().row(),3).data().toString();
                    if (!processPath.isEmpty()) {
                        TCHAR path[255];
                        //获取当前用户的桌面路径
                        SHGetSpecialFolderPath(0, path, CSIDL_DESKTOPDIRECTORY, 0);
                        QString saveIconPath = QFileDialog::getSaveFileName(
                                    this,
                                    tr("保存图标"),
                                    QString::fromWCharArray(path),
                                    tr("ico (*.ico);;"
                                       "Images (*.png *.xpm *.jpg);;"
                                       "all(*.*)"));
                        if (!saveIconPath.isEmpty())
                        {
                            processService.GetFileIcon(processPath).save(saveIconPath);
                        }
                    }
                }
            }


            //切换至模块列表
            if (watched==ui->ButtonThreadToModule)
            {
                ui->stackedWidget->setCurrentWidget(ui->PageModule);
            }
            //刷新线程列表
            if (watched==ui->ButtonThreadRefrensh)
            {
                ProcessBean processBean;
                if (GetSelectProcessInfo(&processBean))
                {
                    this->RefreshProcessThreadListTable(processBean.pId);
                }
            }
            //刷新模块列表
            if (watched==ui->ButtonModuleRefrensh)
            {
                ProcessBean processBean;
                if (GetSelectProcessInfo(&processBean))
                {
                    this->RefreshProcessModuleListTable(processBean.pId);
                }
            }
            //销毁进程
            if (watched==ui->ButtonTerminateProcess)
            {
                ProcessBean processBean;
                if (GetSelectProcessInfo(&processBean))
                {
                    processService.NtTerminateProcessImpl(processBean.pId,PROCESS_EXIT_CODE);
                }
            }

            //结束线程
            if (watched==ui->ButtonThreadTerminate)
            {
                ProcessBean processBean;
                if (GetSelectProcessInfo(&processBean))
                {
                    int threadId=-1;
                    QModelIndex qModelIndex =   ui->TableViewProcessThreadList->currentIndex();
                    threadId = processThreadTableViewDataModule->index(qModelIndex.row(),0).data().toInt();
                    processService.NtTerminateThreadImpl(threadId,PROCESS_EXIT_CODE);
                    this->RefreshProcessThreadListTable(processBean.pId);
                }
            }


            //恢复进程
            if (watched==ui->ButtonResumeProcess) {
                ProcessBean processBean;
                if (GetSelectProcessInfo(&processBean))
                {
                    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,false,processBean.pId);
                    ULONG resume =  processService.NtResumeProcessImpl(hProcess);
                    if (resume!=STATUS_SUCCESS) {
                        qDebug()<<"Suspend fail! ErrorCode:"<<QString("0x%1").arg(resume,8,16, QChar('0'));
                    }
                    //挂起进程后刷新线程列表,方便查看线程状态
                    this->RefreshProcessThreadListTable(processBean.pId);
                    SafeCloseHandle(hProcess);
                }
            }
            //挂起进程
            if (watched==ui->ButtonSuppendProcess)
            {
                ProcessBean processBean;
                if (GetSelectProcessInfo(&processBean))
                {
                    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,false,processBean.pId);
                    //                    int threadId=-1;
                    //                    //如果存在线程列表,则获取第一个线程id.用于失败时执行APC
                    //                    if (processThreadTableViewDataModule->rowCount()) {
                    //                        threadId = processThreadTableViewDataModule->index(0,0).data().toInt();
                    //                    }
                    ULONG Suspend = processService.NtSuspendProcessImpl(hProcess);
                    if (Suspend!=STATUS_SUCCESS) {
                        qDebug()<<"Suspend fail! ErrorCode:"<<QString("0x%1").arg(Suspend,8,16, QChar('0'));
                    }
                    //挂起进程后刷新线程列表,方便查看线程状态
                    this->RefreshProcessThreadListTable(processBean.pId);
                    SafeCloseHandle(hProcess);
                }
            }
            //恢复线程
            if (watched==ui->ButtonThreadResume)
            {
                //获取选中行
                int selectRowIndex =  ui->TableViewProcessThreadList->currentIndex().row();
                if (selectRowIndex>=0) {
                    //获取选中行的模块名称
                    int threadId =  processThreadTableViewDataModule->index(selectRowIndex,0).data().toInt();
                    HANDLE hThread = OpenThread(THREAD_ALL_ACCESS,false,threadId);
                    if (hThread)
                    {
                        //如果成功返回先前挂起次数
                        ULONG suspendCot = ResumeThread(hThread);
                        if (suspendCot==SUSPEND_FAIL_FLAG)
                        {
                            qDebug()<<"恢复线程失败!线程id："<<threadId<<" LastError:"<<GetLastError();
                        }else {
                            qDebug()<<"恢复线程成功!线程id："<<threadId;
                            ProcessBean processBean;
                            if (GetSelectProcessInfo(&processBean))
                            {
                                //恢复线程后刷新线程列表,方便查看线程状态
                                this->RefreshProcessThreadListTable(processBean.pId);
                            }
                        }
                        SafeCloseHandle(hThread);
                    }else {
                        qDebug()<<"OpenThread fail!线程id："<<threadId;
                    }

                }
            }
            //挂起线程
            if (watched==ui->ButtonThreadSuppend)
            {
                //获取选中行
                int selectRowIndex =  ui->TableViewProcessThreadList->currentIndex().row();
                if (selectRowIndex>=0)
                {
                    //获取选中行的模块名称
                    int threadId =  processThreadTableViewDataModule->index(selectRowIndex,0).data().toInt();
                    HANDLE hThread = OpenThread(THREAD_ALL_ACCESS,false,threadId);
                    if (hThread)
                    {
                        //如果成功返回先前挂起次数
                        ULONG suspendCot = SuspendThread(hThread);
                        if (suspendCot==SUSPEND_FAIL_FLAG)
                        {
                            qDebug()<<"挂起线程失败!线程id："<<threadId<<" LastError:"<<GetLastError();
                        }else {
                            qDebug()<<"挂起线程成功!线程id："<<threadId;
                            ProcessBean processBean;
                            if (GetSelectProcessInfo(&processBean))
                            {
                                //挂起线程后刷新线程列表,方便查看线程状态
                                this->RefreshProcessThreadListTable(processBean.pId);
                            }
                        }
                        SafeCloseHandle(hThread);
                    }
                }
            }
            //定位到文件
            if (watched==ui->ButtonPositioningModuleFile)
            {
                //获取选中行
                int selectRowIndex =  ui->TableViewProcessModuleList->currentIndex().row();
                if (selectRowIndex>=0) {
                    //获取选中行的模块名称
                    QString modulePath =  processModuleTableViewDataModule->index(selectRowIndex,0).data().toString();

                    QString qString = QString("%1,%2").arg("/select").arg(modulePath);

                    ShellExecute(
                                NULL,
                                _T("open"),
                                _T("Explorer.exe"),
                                static_cast<const wchar_t*>(qString.toStdWString().c_str()),
                                NULL,
                                SW_SHOWDEFAULT);
                }
            }


            //卸载模块
            if (watched==ui->ButtonUnloadModule)
            {

                ProcessBean processBean;
                if (GetSelectProcessInfo(&processBean))
                {
                    //获取选中行
                    int selectRowIndex =  ui->TableViewProcessModuleList->currentIndex().row();
                    if (selectRowIndex>=0) {
                        QString hBaseString = processModuleTableViewDataModule->index(selectRowIndex,1).data().toString();
                        //获取选中行的模块名称
                        ULONG64 hModuleBase=  hBaseString.replace(0,2,"").toULongLong(NULL,16);
                        systemService.NtUnmapViewOfSectionImpl(processBean.pId,(PVOID)hModuleBase);
                        this->RefreshProcessModuleListTable(processBean.pId);
                    }
                }
            }
        }

    }
    return QWidget::eventFilter(watched,event);
}


//转换汇编代码为机器码
void MainWindow::on_ButtonConvertToMachineCode_clicked()
{
    //汇编代码
    QString assemblyText = ui->TextEditAssembly->toPlainText();
    //如果汇编代码为空,则返回
    if (assemblyText.trimmed().isEmpty())
    {
        ui->TextEditMachineCode->clear();
        ui->TextEditAssembly->setPlaceholderText("多条指令按行分隔");
        return;
    }
    //汇编反汇编基址
    ULONG64 baseAddress = this->GetDisemmblyBaseAddress();
    //获选复选框选中状态,是否OD模式
    bool IsOD = (ui->CheckBoxOD->checkState() == Qt::Checked);
    //获选复选框选中状态,是否为X64模式
    bool IsX64 = (ui->CheckBoxX64->checkState() == Qt::Checked);

    //清空原汇编,重新格式化
    ui->TextEditAssembly->clear();
    //将汇编代码按行分组
    QStringList assemblyTextList = assemblyText.split("\n");
    //汇编解析器对象
    XEDPARSE xedParse;
    //显示的机器码
    QString showTextMachineCode;
    //进行反汇编的行数
    int assemblyListSize = assemblyTextList.size();
    for (int var = 0; var < assemblyListSize; ++var)
    {
        ui->TextEditAssembly->setTextColor(QColor(Qt::black));
        //获取每行的汇编代码
        QString rowAssemblyText =  assemblyTextList.at(var);
        rowAssemblyText =  rowAssemblyText.trimmed();
        if (rowAssemblyText.isEmpty()||
                //如果大出缓冲区长度,则放弃解析
                rowAssemblyText.length()>=100
                )
        {
            //重新获取下一行指令
            continue;
        }

        //解析汇编代码
        bool IsParseOk = disassembleService.ParseAssemble(&xedParse,rowAssemblyText,baseAddress,IsX64);

        if (IsParseOk)
        {
            //如果解析完成(未出现错误指令)
            QString code;
            for (ULONG var = 0; var < xedParse.dest_size; ++var)
            {
                if (!IsOD)
                {
                    code.append("0x");
                }
                code.append(QString("%1").arg(*(PUCHAR)(xedParse.dest+var),2,16,QChar('0')).toUpper());

                if (var!=xedParse.dest_size-1)
                {
                    if (IsOD) {
                        code.append(OD_SPLIT);
                    }else{
                        code.append(NORMAL_SPLIT);
                    }
                }
            }
            showTextMachineCode.append(code);
            //重新回显的指令
            ui->TextEditAssembly->append(rowAssemblyText);
        }else{
            //解析失败时,拼接错误指令
            QString assemblyErrorText;
            ui->TextEditAssembly->setTextColor(QColor(Qt::red));
            assemblyErrorText.append(rowAssemblyText);
            assemblyErrorText.append("                  ");
            assemblyErrorText.append(QString::fromLocal8Bit(xedParse.error));
            ui->TextEditAssembly->append(assemblyErrorText);
        }
        //解析基址,定位到汇编代码下一行地址
        baseAddress+=xedParse.dest_size;
        ui->TextEditAssembly->setTextColor(QColor(Qt::black));
        if (var!=assemblyListSize-1 && !rowAssemblyText.isEmpty() && IsParseOk)
        {
            if (IsOD) {
                showTextMachineCode.append(OD_SPLIT);
            }else{
                showTextMachineCode.append(NORMAL_SPLIT);
            }
        }
        qDebug()<<"machineCode:"<<showTextMachineCode;
    }
    //如果末尾存在分隔符则删除多余分隔符
    if (IsOD) {
        if (showTextMachineCode.endsWith(OD_SPLIT))
        {
            int index = showTextMachineCode.lastIndexOf(OD_SPLIT);
            int length = showTextMachineCode.length();
            showTextMachineCode.remove(index,length-index);
        }
    }else{
        if (showTextMachineCode.endsWith(NORMAL_SPLIT))
        {
            int index = showTextMachineCode.lastIndexOf(NORMAL_SPLIT);
            int length = showTextMachineCode.length();
            showTextMachineCode.remove(index,length-index);
        }
    }

    ui->TextEditMachineCode->setText(showTextMachineCode);

}
//转换机器码为汇编代码
void MainWindow::on_ButtonConvertToAssemblyCode_clicked()
{
    //汇编代码
    QString machineText = ui->TextEditMachineCode->toPlainText();
    //如果汇编代码为空,则返回
    if (machineText.trimmed().isEmpty())
    {
        ui->TextEditAssembly->clear();
        ui->TextEditMachineCode->clear();
        ui->TextEditMachineCode->setPlaceholderText(
                    "多个机器码以','进行分隔,以0x为前缀,示例:0x50,0xE9,0x78,0x56,0x34,0x12"
                    "勾选OD模式以空格' '进行分隔,无进制前缀,示例:50 E9 78 56 34 12"
                    );
        return;
    }
    //获选复选框选中状态,是否为X64模式
    bool IsX64 = (ui->CheckBoxX64->checkState() == Qt::Checked);
    //获选复选框选中状态,是否OD模式
    bool IsOD =  (ui->CheckBoxOD->checkState() == Qt::Checked);
    //清空原汇编,重新格式化
    ui->TextEditAssembly->clear();
    //机器码
    QString machineCode = ui->TextEditMachineCode->toPlainText();

    machineCode.toStdString().c_str();

    //多个机器码以','进行分隔,以0x为前缀,示例:0x50,0xE9,0x78,0x56,0x34,0x12
    //将机器码按","分组
    QStringList machineCodeList;
    if (IsOD)
    {
        machineCodeList =  machineCode.split(OD_SPLIT);
    }else{
        machineCodeList =  machineCode.split(NORMAL_SPLIT);
    }

    //进行汇编的个数
    int machineCodeSize = machineCodeList.size();
    //防止读取buffer时空指针
    PCHAR buffer = new CHAR[machineCodeSize+16];

    for (int var = 0; var < machineCodeSize; ++var)
    {
        QString data = machineCodeList.at(var);
        if (data.startsWith("0X",Qt::CaseInsensitive))
        {
            data.remove(0,2);
        }
        buffer[var]=data.toInt(NULL,16);
    }
    ud_t udObject;
    char assembly[AssemblyStringBufferLength];
    ULONG_PTR  startDisassemble =(ULONG_PTR)buffer;
    //汇编反汇编基址
    ULONG64 baseAddress = this->GetDisemmblyBaseAddress();
    do
    {
        RtlZeroMemory(assembly,AssemblyStringBufferLength);
        ULONG  length = disassembleService.disassemble(&udObject,assembly,baseAddress,startDisassemble,IsX64?Mode64:Mode32);
        //回显反汇编指令
        ui->TextEditAssembly->append(QString::fromLocal8Bit(assembly).toUpper());
        //递增反汇编地址
        startDisassemble+=length;
        baseAddress+=length;
    }while(startDisassemble<((ULONG_PTR)buffer + machineCodeSize));
}
//清空汇编,机器码,基址输入框区域文本
void MainWindow::on_ButtonClearMachineCodeText_clicked()
{
    ui->TextEditMachineCode->clear();
    ui->TextEditAssembly->clear();
    ui->LineEditAssemblyBaseAddress->clear();
}





//获取输入框中的反汇编基址
ULONG64 MainWindow::GetDisemmblyBaseAddress()
{
    //反汇编基址TODO
    QString baseAddressText = ui->LineEditAssemblyBaseAddress->text();
    baseAddressText = baseAddressText.trimmed();
    if (!baseAddressText.isEmpty())
    {
        //如果基址以0x开头,则删除0x前缀
        if (baseAddressText.startsWith("0X",Qt::CaseInsensitive))
        {
            baseAddressText.remove(0,2);
        }
    }
    //汇编反汇编基址
    ULONG64 baseAddress = baseAddressText.toULongLong(NULL,16);
    return baseAddress;
}

//代码注入
void MainWindow::on_ButtonInjectCode_clicked()
{
    ProcessBean processBean;
    if (GetSelectProcessInfo(&processBean))
    {
        HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,false,processBean.pId);
        //在目标进程申请内存空间,用于执行解析后的ShellCode
        PVOID VirBase=NULL;
        PCHAR LocalBuffer=NULL;
        if (hProcess)
        {
            //无法打开进程句柄
            bool IsParseOk=true;
            //汇编代码
            QString assemblyText = ui->TextEditAssembly->toPlainText();
            //如果汇编代码为空,则返回
            if (assemblyText.trimmed().isEmpty())
            {
                ui->TextEditAssembly->clear();
                ui->TextEditAssembly->setPlaceholderText("多条指令按行分隔");
                goto CancelLabel;
            }
            //在目标进程申请内存空间,用于执行解析后的ShellCode
            VirBase =  VirtualAllocEx(hProcess,NULL,PAGE_SIZE,MEM_COMMIT | MEM_RESERVE,PAGE_EXECUTE_READWRITE);
            //汇编反汇编基址
            ULONG64 baseAddress = (ULONG64)VirBase;

            //获选复选框选中状态,是否为X64模式
            bool IsX64 = (ui->CheckBoxX64->checkState() == Qt::Checked);

            //清空原汇编,重新格式化
            ui->TextEditAssembly->clear();
            //将汇编代码按行分组
            QStringList assemblyTextList = assemblyText.split("\n");
            //汇编解析器对象
            XEDPARSE xedParse;
            //显示的机器码
            QString showTextMachineCode;
            //进行反汇编的行数
            int assemblyListSize = assemblyTextList.size();
            //用于缓冲保存本地ShellCode,copy到目标进程
            LocalBuffer = (PCHAR)malloc(PAGE_SIZE);
            ULONG LocalBufferIndex=0;
            for (int var = 0; var < assemblyListSize; ++var)
            {
                ui->TextEditAssembly->setTextColor(QColor(Qt::black));
                //获取每行的汇编代码
                QString rowAssemblyText =  assemblyTextList.at(var);
                rowAssemblyText =  rowAssemblyText.trimmed();
                if (rowAssemblyText.isEmpty()||
                        //如果大出缓冲区长度,则放弃解析
                        rowAssemblyText.length()>=100
                        )
                {
                    //重新获取下一行指令
                    continue;
                }

                //解析汇编代码
                bool IsParseOk = disassembleService.ParseAssemble(&xedParse,rowAssemblyText,baseAddress,IsX64);

                if (IsParseOk)
                {
                    //如果解析完成(未出现错误指令)
                    memmove((PVOID)(&LocalBuffer[LocalBufferIndex]),xedParse.dest,xedParse.dest_size);
                    LocalBufferIndex+=xedParse.dest_size;
                    //重新回显的指令
                    ui->TextEditAssembly->append(rowAssemblyText);
                }else{
                    //解析失败时,拼接错误指令
                    QString assemblyErrorText;
                    ui->TextEditAssembly->setTextColor(QColor(Qt::red));
                    assemblyErrorText.append(rowAssemblyText);
                    assemblyErrorText.append("                  ");
                    assemblyErrorText.append(QString::fromLocal8Bit(xedParse.error));
                    ui->TextEditAssembly->append(assemblyErrorText);
                    IsParseOk = false;
                }
                //解析基址,定位到汇编代码下一行地址
                baseAddress+=xedParse.dest_size;
                ui->TextEditAssembly->setTextColor(QColor(Qt::black));

                qDebug()<<"machineCode:"<<showTextMachineCode;
            }
            //添加return,防止shellcode未返回,线程崩溃
            LocalBuffer[LocalBufferIndex]=0xc3;
            SIZE_T writeSize=0;
            WINBOOL writeOk=false;
            //远程线程句柄,用于执行写入目标进程的ShellCode
            HANDLE hThread=NULL;
            if (IsParseOk)
            {
                //如果勾选X64,则解析为64位代码,而目标进程为32,则提醒
                if (IsX64 && processBean.bit==Mode32) {
                    int ret = QMessageBox::warning(
                                this, tr("代码注入"),
                                tr("已勾选X64,当前进程为32位(64位和32位指令在解析时存在较大差别)\n"
                                   "确认要继续吗？"),
                                QMessageBox::Ok |  QMessageBox::Cancel,//显示哪些按钮
                                QMessageBox::Ok);//默认选中哪个按钮
                    switch (ret) {
                    case QMessageBox::Ok:
                    {
                        SIZE_T writeSize=0;
                        WINBOOL writeOk =  WriteProcessMemory(hProcess,VirBase,LocalBuffer,PAGE_SIZE,&writeSize);
                        if (writeOk && writeSize==PAGE_SIZE)
                        {
                            qDebug()<<"已写入ShellCode到进程ID:"<<processBean.pId<<" Name:"<<processBean.pName<<"VirtualAddress:"<<VirBase;
                        }
                        break;
                    }
                    case QMessageBox::Cancel:
                        // Cancel was clicked
                        goto CancelLabel;
                    default:
                        break;
                    }

                }else if (!IsX64 && processBean.bit==Mode64) {
                    //如果未勾选X64,则解析为32位代码,而目标进程为64,则提醒
                    int ret = QMessageBox::warning(
                                this, tr("代码注入"),
                                tr("未勾选X64,当前进程为64位(64位和32位指令在解析时存在较大差别)\n"
                                   "确认要继续吗？"),
                                QMessageBox::Ok |  QMessageBox::Cancel,//显示哪些按钮
                                QMessageBox::Ok);//默认选中哪个按钮
                    switch (ret) {
                    case QMessageBox::Ok:
                    {
                        goto WriteLabel;
                        break;
                    }
                    case QMessageBox::Cancel:
                        // Cancel was clicked
                        goto CancelLabel;
                    default:
                        // should never be reached
                        break;
                    }
                }

WriteLabel:
                writeOk =  WriteProcessMemory(hProcess,VirBase,LocalBuffer,PAGE_SIZE,&writeSize);
                if (writeOk && writeSize==PAGE_SIZE)
                {
                    qDebug()<<"已写入ShellCode到进程ID:"<<processBean.pId<<" Name:"<<processBean.pName<<"VirtualAddress:"<<VirBase;
                }

                systemService.NtCreateThreadEx(
                            &hThread
                            ,0x1FFFFF
                            ,NULL
                            ,hProcess
                            ,VirBase
                            ,NULL
                            ,FALSE
                            ,0
                            ,0
                            ,0
                            ,NULL);
            }
        }
CancelLabel:
        SafeFree(LocalBuffer);
        SafeCloseHandle(hProcess);
        return;
    }
}



void MainWindow::on_ButtonStartDriver_clicked()
{
    QString file = ui->LineEditDriverPath->text();
    //如果未选中文件
    if (file.isEmpty()) {
        return;
    }
    //如果后缀不是驱动格式,则返回
    QFileInfo fileInfo(file);
    if (!fileInfo.fileName().endsWith(SYS_SUFFIX,Qt::CaseInsensitive)) {
        return;
    }
    QString  driverName = fileInfo.baseName();
    std::wstring dwstr =  driverName.toStdWString();
    std::wstring serviceName =  file.toStdWString();
    bool IsOk =   driverService.ManageDriver(dwstr.c_str(),serviceName.c_str(),DRIVER_FUNC_INSTALL);
    QList<QStandardItem*> item;
    item<<new QStandardItem(driverName)
       <<new QStandardItem("Start")
      <<new QStandardItem(IsOk?"SUCCESS":"UnSuccessful")
     <<new QStandardItem(systemService.GetLastErrorText(driverService.GetDriverManagerLastErrorCode()));
    DriverTableViewDataModule->appendRow(item);
    ui->TableViewShowDriverLogger->scrollToBottom();
}

void MainWindow::on_ButtonStopDriver_clicked()
{
    QString file = ui->LineEditDriverPath->text();
    //如果未选中文件
    if (file.isEmpty()) {
        return;
    }
    //如果后缀不是驱动格式,则返回
    QFileInfo fileInfo(file);
    if (!fileInfo.fileName().endsWith(SYS_SUFFIX,Qt::CaseInsensitive)) {
        return;
    }
    QString  driverName = fileInfo.baseName();
    std::wstring dwstr =  driverName.toStdWString();
    std::wstring serviceName =  file.toStdWString();
    bool IsOk =   driverService.ManageDriver(dwstr.c_str(),serviceName.c_str(),DRIVER_FUNC_REMOVE);
    QList<QStandardItem*> item;
    item<<new QStandardItem(driverName)
       <<new QStandardItem("Stop")
      <<new QStandardItem(IsOk?"SUCCESS":"UnSuccessful")
     <<new QStandardItem(systemService.GetLastErrorText(driverService.GetDriverManagerLastErrorCode()));
    DriverTableViewDataModule->appendRow(item);
    ui->TableViewShowDriverLogger->scrollToBottom();
}



void MainWindow::on_ButtonSelectDriverFile_clicked()
{
    TCHAR path[255];
    //获取当前用户的桌面路径
    SHGetSpecialFolderPath(0, path, CSIDL_DESKTOPDIRECTORY, 0);
    QString DriverPath = QFileDialog::getOpenFileName(
                this
                ,tr("Open Text")
                ,QString::fromWCharArray(path)
                ,tr("Driver File (*.sys);;all(*.*)"));
    ui->LineEditDriverPath->setText(DriverPath);
}


//清空驱动安装的日志
void MainWindow::on_ButtonClearLoggerTableView_clicked()
{
    DriverTableViewDataModule->removeRows(0,DriverTableViewDataModule->rowCount());
}

//创建远程线程
void MainWindow::on_ButtonCreateThread_clicked()
{
    ProcessBean processBean;
    if (GetSelectProcessInfo(&processBean))
    {
        DialogRemoteThreadParam* dialogRemoteThreadParam = new DialogRemoteThreadParam();

        dialogRemoteThreadParam->setModal(true);
        int ret = dialogRemoteThreadParam->exec();
        qDebug()<<"ret:"<<ret;
        if(ret==QDialog::Accepted)
        {
            qDebug()<<"Accepted";
            ULONG_PTR threadEntry =  dialogRemoteThreadParam->GetThreadEntryValue();
            ULONG_PTR threadParam =  dialogRemoteThreadParam->GetThreadParamValue();
            int threadFlag =  dialogRemoteThreadParam->GetRadioButtonValue();
            //销毁Dialog对话框
            SafeDelete(dialogRemoteThreadParam);

            qDebug()<<"threadEntry:"<<threadEntry;
            qDebug()<<"threadParam:"<<threadParam;
            qDebug()<<"radioButtonValue:"<<threadFlag;
            //判断输入的地址是否有效
            if (!threadEntry || processBean.pId==GetCurrentProcessId())
            {
                return;
            }
            HANDLE hProcess =  OpenProcess(PROCESS_ALL_ACCESS,false,processBean.pId);
            HANDLE hThread=NULL;
            systemService.NtCreateThreadEx(
                        &hThread
                        ,0x1FFFFF
                        ,NULL
                        ,hProcess
                        ,(PVOID)threadEntry
                        ,(PVOID)threadParam
                        ,threadFlag
                        ,0
                        ,0
                        ,0
                        ,NULL);
            if (!hThread)
                qDebug()<<"NtCreateThreadEx Fail！LastError:"<<GetLastError();
        }
        if(ret==QDialog::Rejected)
        {
            qDebug()<<"Rejected";
        }
    }
}
